package com.punch.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.system.BannerDTO;
import com.punch.common.exception.BusinessException;
import com.punch.common.page.PageInfo;
import com.punch.common.query.syste.BannerQueryInfo;
import com.punch.common.simple.redis.utils.UserUtil;
import com.punch.common.tools.BasePage;
import com.punch.common.utils.ImageUtil;
import com.punch.common.vo.system.BannerVO;
import com.punch.system.exception.SysExceptionEnum;
import com.punch.system.mapper.SysBannerMapper;
import com.punch.system.model.SysBanner;
import com.punch.system.model.SysNationArea;
import com.punch.system.service.BannerService;
import com.punch.system.service.NationAreaService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * banner管理 服务实现类
 * </p>
 *
 * @author wjj
 * @since 2020-12-14
 */
@Service
public class BannerServiceImpl extends ServiceImpl<SysBannerMapper, SysBanner> implements BannerService {

    @Resource
    private NationAreaService nationAreaService;

    /**
     * banner分页
     *
     * @param queryInfo 查询条件
     * @return PageInfo<BannerVO>
     */
    @Override
    public PageInfo<BannerVO> listBanner(BannerQueryInfo queryInfo) {
        queryInfo.setSortStr("update_time");
        queryInfo.setCurrentAreaId(UserUtil.getLoginUser().getAreaId());
        return BasePage.queryBasePage(queryInfo, params -> this.getBaseMapper().queryCount(params),
                params -> {
                    List<BannerVO> retList = getBaseMapper().queryList(params);
                    retList.forEach(bannerVO -> {
                        if (bannerVO.getStatus() == 0) {
                            bannerVO.setUpdateTime(null);
                        }
                        if (StrUtil.isNotEmpty(bannerVO.getBannerImg())) {
                            bannerVO.setBannerImg(ImageUtil.addPrefix(bannerVO.getBannerImg()) + "?x-oss-process=image/resize,l_100,m_mfit");
                        }
                    });
                    return retList;
                });
    }

    /**
     * 保存banner
     *
     * @param bannerDTO 提交表单
     * @return id
     */
    @Override
    public Integer saveBanner(BannerDTO bannerDTO) {
        //设置父地区
        Integer areaId = bannerDTO.getAreaId();
        //数量限制
        validateCount(areaId, 8, bannerDTO.getFloor());
        SysBanner sysBanner = new SysBanner();
        BeanUtil.copyProperties(bannerDTO, sysBanner);
        Long userId = UserUtil.getLoginUserId();
        sysBanner.setCreateId(userId);

        SysNationArea area = nationAreaService.getById(areaId);
        sysBanner.setAllAreaIds(area.getParentIds() + "," + areaId);
        if (StrUtil.isNotEmpty(bannerDTO.getBannerImg())) {
            sysBanner.setBannerImg(ImageUtil.removePrefix(bannerDTO.getBannerImg()));
        }
        if (!save(sysBanner)) {
            throw new BusinessException(SysExceptionEnum.DATA_INSERT_EXCEPTION);
        }
        return sysBanner.getId();
    }

    /**
     * 修改banner
     *
     * @param bannerDTO 提交表单
     * @return id
     */
    @Override
    public Integer updateBanner(BannerDTO bannerDTO) {
        Integer areaId = bannerDTO.getAreaId();
        //数量限制
        validateCount(areaId, 8, bannerDTO.getFloor());
        SysBanner sysBanner = new SysBanner();
        BeanUtil.copyProperties(bannerDTO, sysBanner);
        sysBanner.setId(bannerDTO.getBannerId());
        if (StrUtil.isNotEmpty(bannerDTO.getBannerImg())) {
            sysBanner.setBannerImg(ImageUtil.removePrefix(bannerDTO.getBannerImg()));
        }
        if (!updateById(sysBanner)) {
            throw new BusinessException(SysExceptionEnum.DATA_UPDATE_EXCEPTION);
        }
        return sysBanner.getId();
    }

    /**
     * banner详情
     *
     * @param bannerId bannerId
     * @return BannerVO
     */
    @Override
    public BannerVO getBanner(Integer bannerId) {
        SysBanner sysBannerEX = getById(bannerId);
        Optional.ofNullable(sysBannerEX).orElseThrow(() -> new BusinessException(SysExceptionEnum.DATA_NOT_EXIST));
        BannerVO bannerVO = new BannerVO();
        BeanUtil.copyProperties(sysBannerEX, bannerVO);
        if (StrUtil.isNotEmpty(sysBannerEX.getBannerImg())) {
            bannerVO.setBannerImg(ImageUtil.addPrefix(sysBannerEX.getBannerImg()));
        }
        bannerVO.setBannerId(bannerId);
        return bannerVO;
    }

    /**
     * 删除banner
     *
     * @param bannerId bannerId
     * @return id
     */
    @Override
    public Integer deleteBanner(Integer bannerId) {
        SysBanner sysBannerEX = getById(bannerId);
        Optional.ofNullable(sysBannerEX).orElseThrow(() -> new BusinessException(SysExceptionEnum.DATA_NOT_EXIST));
        //已经展示的不能删除,需要下架
        if (sysBannerEX.getStatus() == 1) {
            throw new BusinessException(SysExceptionEnum.STATUS_ERROR);
        }
        if (!removeById(bannerId)) {
            throw new BusinessException(SysExceptionEnum.DATA_DELETION_EXCEPTION);
        }
        return bannerId;
    }

    /**
     * 修改banner状态
     *
     * @param bannerId bannerId
     * @param status   状态 0-不显示 1-显示
     * @return bannerId
     */
    @Override
    public Integer updateBannerStatus(Integer bannerId, Integer status) {
        SysBanner sysBannerEX = getById(bannerId);
        Optional.ofNullable(sysBannerEX).orElseThrow(() -> new BusinessException(SysExceptionEnum.DATA_NOT_EXIST));
        if (sysBannerEX.getStatus().equals(status)) {
            throw new BusinessException(SysExceptionEnum.STATUS_ERROR);
        }
        SysBanner sysBanner = new SysBanner();
        sysBanner.setStatus(status);
        sysBanner.setId(bannerId);
        if (!updateById(sysBanner)) {
            throw new BusinessException(SysExceptionEnum.DATA_UPDATE_EXCEPTION);
        }
        return bannerId;
    }

    /**
     * 同一地区下最大数量
     *
     * @param areaId   地区id
     * @param maxCount 最大数量
     * @param floor    楼层
     */
    private void validateCount(Integer areaId, Integer maxCount, String floor) {
        QueryWrapper<SysBanner> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysBanner::getAreaId, areaId).eq(SysBanner::getFloor, floor);
        if (count(queryWrapper) >= maxCount) {
            throw new BusinessException(SysExceptionEnum.EXCEED_MAX_COUNT);
        }
    }
}
